#pragma once
#include "../CommonModule/comm.hpp"

using epoll_events_array_ptr = struct epoll_event *;

class Epoller
{
private:
    static const int defaultmaxevents = 32;
    static const int size = 128;
    static const int defaulttimeout = -1;

public:
    void Create()
    {
        _epfd = epoll_create(size);
        if (_epfd < 0)
        {
            ELOG("epoll model create failed");
            exit(EpollCreate_Error);
        }
    }

    void Add(int fd, uint32_t event)
    {
        struct epoll_event ee;
        ee.data.fd = fd;
        ee.events = event;
        int ret = epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &ee);
        if (ret < 0)
        {
            ELOG("add fd to epoll model failed");
            return;
        }
        fd_list.insert(fd);

    }

    void Mod(int fd, uint32_t event)
    {
        struct epoll_event ee;
        ee.data.fd = fd;
        ee.events = event;
        int ret = epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &ee);
        if (ret < 0)
        {
            ELOG("mod fd to epoll model failed");
            return;
        }
    }

    void Del(int fd)
    {
        int ret = epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr);
        if (ret < 0)
        {
            ELOG("del fd to epoll model failed");
            return;
        }
        fd_list.erase(fd);
    }

    int Wait()
    {
        return epoll_wait(_epfd, _epoll_events_array, defaultmaxevents, defaulttimeout);
    }

    void PrintBug()
    {
        DLOG("fd_list: ");
        for(auto e : fd_list)
        {
            DLOG("%d ", e);
        }
        std::cout << std::endl;
    }

    void Close()
    {
        if (_epfd > 0)
        {
            close(_epfd);
        }
    }

    epoll_events_array_ptr GetEpollEvents()
    {
        return _epoll_events_array;
    }

private:
    int _epfd = -1;
    struct epoll_event _epoll_events_array[defaultmaxevents];
    
    // 做测试用
    std::set<int> fd_list;
};